<template>
    <div class="verification-page">
        <div class="header">
            <div class="left">
                漏洞管理
                <Select filterable transfer 
                    v-model="vulnerabilityId" 
                    placeholder=""
                    filterable
                    clearable
                    style="width:204px;text-align: left;margin-left: 15px;" 
                    @on-change="changeVulnerability">
                    <Option v-for="item in allVulnerabilityList" :value="item.vulnerabilityId" :title="item.vulnerabilityName" :key="item.id">{{ item.vulnerabilityName }}</Option>
                </Select>
                <Button
                    style="height: 32px;margin-left: 9px;"
                    @click="showManageDrawer">
                    <Icon size="16" type="ios-add" /> 漏洞管理
                </Button>
            </div>
            <ul class="right">
                <li>
                    <Dropdown trigger="click" style="margin-left: 20px" placement="bottom-end">
                        <a href="javascript:void(0)">
                            账号密码
                            <Icon type="ios-arrow-down"></Icon>
                        </a>
                        <DropdownMenu slot="list">
                            <DropdownItem>账号：{{this.userName}}</DropdownItem>
                            <DropdownItem>密码：{{this.pwd}}</DropdownItem>
                        </DropdownMenu>
                    </Dropdown>
                </li>
                <li>
                    <Dropdown class="my-dropdown">
                        <Icon type="md-desktop" size="18"></Icon>
                        <span style="width:100px;cursor: pointer">{{this.curVmName}}({{this.curAccess}})</span>
                        <Icon type="ios-arrow-down"></Icon>
                        <DropdownMenu slot="list" >
                            <DropdownItem v-for="vm in vmList" :key="vm.id">
                                <Dropdown placement="right-start" @on-click="getCurVm" id="childMenu">
                                    <DropdownItem :name="vm.id">
                                        <Icon type="md-desktop" style="margin-right:5px"/>
                                        {{vm.name}}
                                        <Icon type="ios-arrow-forward"></Icon>
                                    </DropdownItem>
                                    <DropdownMenu slot="list">
                                        <DropdownItem  v-for="access in vm.access" :key="access.accessType" :name="JSON.stringify({vm:vm,access:access})">{{access.accessType}}</DropdownItem>
                                    </DropdownMenu>
                                </Dropdown>
                            </DropdownItem>
                        </DropdownMenu>
                    </Dropdown>
                </li>
            </ul>
        </div>
        <div class="content">
            <div class="content-flex">
                <div class="poc-list">
                    POC:
                    <Input clearable v-model="poc" type="textarea" disabled></Input>
                </div>
                <div class="desktop">
                    <iframe style="width: 100%; height: 100%;" :src="curVmUrl" frameborder="0" id="environ" @mouseover="setFocus"></iframe>
                </div>
            </div>
            <Spin size="large"  fix v-if="spinShow">
                <Icon type="ios-loading" size="18" class="demo-spin-icon-load"></Icon>
                <div>机器连接中，请稍后...</div>
            </Spin>
        </div>
        <Drawer
            title="关联漏洞管理"
            v-model="drawer.show"
            width="720"
            class="my-sub-element">
            <MenuPage
                :data="resData.list"
                :columns="columns"
                :page.sync="queryParams.pageIndex"
                :size.sync="queryParams.pageSize"
                :total="resData.total"
                :loading="resData.loading"
                class="my-menu-page"
                @queryFun="getVulnerabilityVerifyProjectList">
                <template slot="search">
                    <Button ghost style="height: 32px;" type="primary" class="md-add-jh" @click="showModal">关联漏洞</Button>
                    <Input
                        clearable
                        v-model.trim="queryParams.vulnerabilityName"
                        placeholder="漏洞名称"
                        @on-change="debounceFn"
                        style="width: 180px;margin-left: 15px;" />
                    <Input
                        clearable
                        v-model.trim="queryParams.cve"
                        placeholder="CVE"
                        @on-change="debounceFn"
                        style="width: 180px;margin-left: 15px;" />
                    <Button
                        type="primary"
                        ghost
                        style="height: 32px;margin-left: 9px;"
                        @click="refreshQueryParams()">
                        <i class="el-icon-refresh-right" />
                    </Button>
                </template>
            </MenuPage>
        </Drawer>
        <Modal
            v-model="modalData.show"
            title="关联漏洞"
            @on-visible-change="changeVisible"
            class="my-modal">
            <Form 
                ref="formInline"
                :label-width="80"
                :model="formInline" 
                :rules="ruleInline">
                <FormItem prop="ids"  label="公共漏洞">
                    <!-- 需要手动校验一下，不然不清楚为什么校验不准确 -->
                    <public-vulnerability-select-drawer
                        v-model="formInline.ids"
                        ref="publicVulnerabilitySelectDrawer"
                        @input="validateVulnerabilityIds"
                        :inner="true"></public-vulnerability-select-drawer>
                </FormItem>
            </Form>
            <div slot="footer" class="footer">
                <Button @click="modalData.show = false">取消</Button>
                <Button @click="saveVerifyList" :loading="modalData.loading" type="primary">确定</Button>
            </div>
        </Modal>
    </div>
</template>

<script>
import { 
    getVulnerabilityVerifyProjectList,
    addVulnerabilityVerifyProject,
    deleteVulnerabilityVerifyProject
} from '@/view/testPlatform/vulnerability/api/vulnerabilityVerifyProject'
import { queryCommonVulnerabilityList } from '@/view/testPlatform/components/public-vulnerability-select-drawer/vulnerability'
import { getProjectVmList, vmAccess } from '@/view/testPlatform/vulnerability/api/topo'
import { debounce } from '@/libs/utils'
import PublicVulnerabilitySelectDrawer from '@/view/testPlatform/components/public-vulnerability-select-drawer'
import cookieUse from '@/libs/cookie.js'

export default {
    name: 'VerificationPage',
    components: { 
        PublicVulnerabilitySelectDrawer
    },
    props: {
    },
    data() {
        return {
            projectId: this.$route.query.projectId,
            allVulnerabilityList: [],
            vulnerabilityId: '',
            vmId: '',
            userName: '',
            pwd: '',
            curVmName: '',
            curAccess: '',
            vmList: [],
            spinShow: false,
            curVmUrl: '',
            poc: '',
            drawer: {
                show: false
            },
            columns: [
                {
                    placement: 'top-left',
                    title: '漏洞名称',
                    key: 'vulnerabilityName',
                    tooltip: true,
                    width: 320,
                },
                {
                    title: 'CVE',
                    key: 'cve',
                    tooltip: true,
                    width: 120,
                },
                {
                    title: '操作',
                    width: 60,
                    slot: 'action',
                    opList: [
                        {
                            txt: '删除',
                            tooltip: true,
                            type: 'delete',
                            title: '确定要删除吗？',
                            on:{
                                click:(data,e) => {
                                this.deleteItem([data.id])
                                }
                            },
                            disabled: (data)=>data.isUsed
                        }
                    ]
                }
            ],
            resData: {
                total: 0,
                list: [],
                loading: true
            },
            queryParams: {
                pageIndex: 1,
                pageSize: 10,
                projectId: this.projectId,
                vulnerabilityName: '',
                cve: ''
            },
            formInline: {
                ids: []
            },
            ruleInline: {
                ids: [
                    { required: true, type: 'array', message: '关联漏洞不能为空', trigger: 'blur,change' }
                ],
            },
            modalData: {
                show: false,
                loading: false
            },
        }
    },
    mounted() {
        this.getAllVulnerabilityList()
        this.getVmList()
        this.getToken = cookieUse.getCookie('desig-token') || ''
    },
    methods: {
        // 漏洞修改后，需要验证
        validateVulnerabilityIds() {
            this.$nextTick(() => {
                this.$refs.formInline.validateField('ids')
            })
        },
        // 防抖方法，用于输入型查询
        debounceFn: debounce(function() {
            this.changePageNow(1)
        }),
        // 获取工程中的虚拟机
        getVmList() {
            getProjectVmList(this.projectId).then(({ code, message, data = {} }) => {
                if (code !== 1) {
                    this.$Message.warning(message)
                    return
                }
                let vms = data.list || []
                if (!vms.length) {
                    this.$Message.warning('未获取到可访问的虚拟机，请确认该工程是否已部署成功')
                    return
                }
                this.vmList = vms;
                if(!this.vmId){
                    this.curVmName = vms[0].name;
                    this.userName = vms[0].access[0].username;
                    this.pwd = vms[0].access[0].password;
                    this.curVmOsId = vms[0].id;
                    this.curAccess = vms[0].access[0].accessType;
                    this.openConsole(this.curAccess,this.curVmOsId);
                }else{
                    let curVms = vms.filter(vm => vm.id == this.vmId)
                    if(curVms.length > 0){
                    this.curVmName = curVms[0].name;
                    this.userName = curVms[0].access[0].username;
                    this.pwd = curVms[0].access[0].password;
                    this.curVmOsId = curVms[0].id;
                    this.curAccess = this.accessType;
                    this.openConsole(this.accessType,this.curVmOsId);
                    }else{
                    this.curVmName = vms[0].name;
                    this.userName = vms[0].access[0].username;
                    this.pwd = vms[0].access[0].password;
                    this.curVmOsId = vms[0].id;
                    this.curAccess = vms[0].access[0].accessType;
                    this.openConsole(this.curAccess,this.curVmOsId);
                    }
                }
            }).catch(() => {
                this.$Message.error('获取工程下的虚拟机异常')
            })
        },
        // 替换漏洞，获取对应的POC
        changeVulnerability(val) {
            this.poc = ''
            if (!val) {
                return
            }
            this.poc = '获取中...'
            queryCommonVulnerabilityList({
                pageIndex: 1,
                pageSize: 1,
                id: val
            }).then(({ data = {} }) => {
                let { code, message } = data
                if (code !== 1) {
                    this.$Message.warning(message)
                    return
                }
                data = data.data || {}
                let items = (data.items || [])[0] || {}
                this.poc = items.vulnerabilityPoc && items.vulnerabilityPoc.poc
            }).catch(() => {
                this.$Message.error('获取公共漏洞异常')
            })
        },
        // 删除漏洞
        deleteItem(ids) {
            deleteVulnerabilityVerifyProject(ids).then(({ code, message }) => {
                if (code !== 1) {
                    this.$Message.warning(message)
                    return
                }
                this.$Message.success(`删除漏洞成功`)
                // 删除后展示当前页，当前页没有数据展示前一页
                this.queryParams.pageIndex = (this.resData.list.length == ids.length && this.queryParams.pageIndex > 1) ?
                                this.queryParams.pageIndex - 1 : this.queryParams.pageIndex;
                this.getVulnerabilityVerifyProjectList()
                this.getAllVulnerabilityList()
            }).catch(() => {
                this.$Message.error(`删除漏洞异常`)
            })
        },
        // 隐藏模态框时，重置表单数据
        changeVisible(type) {
            if (!type) {
                this.$refs.formInline.resetFields()
                this.modalData.loading = false
                this.$refs.publicVulnerabilitySelectDrawer.clear()
            }
        },
        // 批量关联漏洞
        saveVerifyList() {
            this.$refs.formInline.validate(valid => {
                if (valid) {
                    this.modalData.loading = true
                    addVulnerabilityVerifyProject(this.projectId, this.formInline.ids).then(({ code, message }) => {
                        if (code !== 1) {
                            this.$Message.warning(message)
                            return
                        }
                        this.$Message.success('关联漏洞成功')
                        this.modalData.show = false
                        this.refreshQueryParams()
                        this.getAllVulnerabilityList()
                    }).catch(() => {
                        this.$Message.error('关联漏洞异常')
                    }).finally(() => {
                        this.modalData.loading = false
                    })
                }
            })
        },
        // 获取所有已配置的漏洞
        getAllVulnerabilityList() {
            getVulnerabilityVerifyProjectList({
                pageIndex: 1,
                pageSize: 2147483646,
                projectId: this.projectId
            }).then(({ code, message, data }) => {
                if (code !== 1) {
                    this.$Message.warning(message)
                    return
                }
                this.allVulnerabilityList = data.items || []
                if (this.allVulnerabilityList.length) {
                    let template = this.allVulnerabilityList.find(item => item.vulnerabilityId === this.vulnerabilityId)
                    if (!template) { // 当前选中的值已经不存在了，自动选中第一条数据
                        this.vulnerabilityId = this.allVulnerabilityList[0].vulnerabilityId
                        this.changeVulnerability(this.vulnerabilityId)
                    }
                } else { // 没有数据不展示
                    this.vulnerabilityId = ''
                    this.changeVulnerability(this.vulnerabilityId)
                }
            }).catch(() => {
                this.$Message.error('获取关联漏洞列表异常')
            })
        },
        // 打开模态框，视接口返回的数据结构进行后续处理，暂时未完成功能
        showModal() {
            this.modalData.show = true
            this.$refs.publicVulnerabilitySelectDrawer.getCheckList(this.allVulnerabilityList.map(item => item.vulnerabilityId).join(','))
        },
        // 重置搜索条件并查询数据
        refreshQueryParams() {
            this.queryParams = {
                pageIndex: 1,
                pageSize: 10,
                projectId: this.projectId,
                vulnerabilityName: '',
                cve: ''
            }
            this.changePageNow(1);
        },
        // 查询指定页数据
        changePageNow(val) {
            this.queryParams.pageIndex = val || this.queryParams.pageIndex;
            this.getVulnerabilityVerifyProjectList();
        },
        // 查询关联漏洞列表
        getVulnerabilityVerifyProjectList() {
            this.resData.loading = true
            getVulnerabilityVerifyProjectList(this.queryParams).then(({ code, message, data = {} }) => {
                if (code !== 1) {
                    this.$Message.warning(message)
                    return
                }
                this.resData = {
                    total: data.total || 0,
                    list: data.items || []
                }
            }).catch(() => {
                this.$Message.error('获取关联漏洞列表异常')
            }).finally(() => {
                this.resData.loading = false
            })
        },
        // 打开漏洞管理页面
        showManageDrawer() {
            this.drawer.show = true
            this.refreshQueryParams()
        },
        // 切换机器
        getCurVm(vmObj){
            var s = vmObj.substr(0,1);
            if(s === '{' ){
                let vm = JSON.parse(vmObj);
                this.curVm = vm;
                this.curVmName = vm.vm.name;
                this.curVmOsId = vm.vm.id;
                this.userName = vm.access.username;
                this.pwd = vm.access.password;
                this.curAccess = vm.access.accessType;
                this.openConsole(vm.access.accessType,this.curVmOsId);
                sessionStorage.setItem('accessType',this.curAccess);
                sessionStorage.setItem('curVmOsId',this.curVmOsId);
            }
        },
        // 鼠标移入时 试验机获取焦点
        setFocus() {
            document.getElementById('environ').contentWindow.focus();
        },
        openConsole(type,vmId){
            this.spinShow = true
            vmAccess(vmId,type).then(({ code, message, attribute = {} }) =>  {
                if (code !== 1) {
                    this.$Message.warning(message)
                    return
                }
                let url = attribute.url;
                this.curVmUrl = `${url}&Authorization=${this.getToken}`;
            }).catch(() => {
                this.$Message.error('连接虚拟机异常')
            }).finally(() => {
                this.spinShow = false
            })
        },
    }
}
</script>

<style scoped>
.verification-page {
    width: 100vw;
    height: 100vh;
    overflow: hidden;
}
.header {
    height: 60px;
    line-height: 60px;
    margin-bottom: 3px;
    background: var(--card-body-bgcolor);
    color: var(--default-btn-color);
    overflow: hidden;
    -webkit-box-shadow: 0 0 5px 1px #515a6e;
    box-shadow: 0 0 5px 1px #515a6e;
    display: flex;
    justify-content: space-between;
    padding: 0 20px;
}
.right{
    display: flex;
    justify-content: flex-start;
    align-items: center;
}
.right>li{
    margin-left: 30px;
}
.content {
    width: 100%;
    height: calc(100% - 60px);
}
.content-flex {
    width: 100%;
    height: 100%;
    display: flex;
}
.poc-list {
    width: 420px;
    height: 100%;
    padding: 10px;
    background-color: var(--card-body-bgcolor);
}

.desktop {
    height: 100%;
    width: calc(100% - 420px);
}

.poc-list /deep/ .ivu-input-type-textarea {
    margin-top: 10px;
    height: calc(100% - 34px);
}

.poc-list /deep/ .ivu-input-type-textarea .ivu-input {
    height: 100%;
    resize: none;
    cursor: auto;
    background-color: var(--card-body-bgcolor) !important;
    color: #515a6e !important;
}
.my-sub-element /deep/ .my-menu-page {
    margin: 0;
}
.my-sub-element /deep/ .my-menu-page .search-wrapper {
    width: 100%;
}

.my-dropdown /deep/ .ivu-select-dropdown {
    overflow: unset !important;
}
</style>